home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / parse / parse.c oldauth < prev    next >
Encoding:
Text File  |  1994-06-22  |  46.9 KB  |  1,474 lines

  1. /****************************************************************
  2. *    NCSA Telnet for the Macintosh                                *
  3. *                                                                *
  4. *    National Center for Supercomputing Applications                *
  5. *    Software Development Group                                    *
  6. *    152 Computing Applications Building                            *
  7. *    605 E. Springfield Ave.                                        *
  8. *    Champaign, IL  61820                                        *
  9. *                                                                *
  10. *    Copyright (c) 1986-1992,                                    *
  11. *    Board of Trustees of the University of Illinois                *
  12. ****************************************************************/
  13.  
  14. #ifdef MPW
  15. #pragma segment 4
  16. #endif
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20.  
  21. #include "TelnetHeader.h"
  22. #include "parse.h"                // For our #defines
  23. #include "wind.h"                /* For WindRec structure */
  24. #include "network.proto.h"                /* For net functions */
  25. #include "debug.h"                /* For putln proto */
  26. #include "vgtek.proto.h"
  27. #include "vsdata.h"
  28. #include "vsinterf.proto.h"
  29. #include "maclook.proto.h"
  30. #include "tekrgmac.proto.h"
  31. #include "menuseg.proto.h"
  32.  
  33. #include "vr.h"
  34. #include "vr.proto.h"
  35. #ifdef newauth                            /* (RW) */
  36. #include "tnae.h"
  37. #include "authencrypt.h"
  38. #include "authencrypt.proto.h"
  39. #else
  40. #include "encrypt.proto.h"
  41. #include "kerberos.proto.h"
  42. #endif
  43. #include "wdefpatch.proto.h"
  44.  
  45. //#define    OPTS_DEBUG
  46. #ifdef    OPTS_DEBUG
  47. #define    opts_debug_print(x)    putln(x)    
  48. #include "optsdebug.h"
  49. #else
  50. #define    opts_debug_print(x)
  51. #endif
  52.  
  53. #define    SEND_NOSUPPORT_ON_SLC_INIT    1
  54.  
  55. extern short     scrn;
  56. extern WindRec    *screens;
  57.  
  58. #include "parse.proto.h"
  59.  
  60. /*********************************************************************/
  61. /*  parse
  62. *   look at the string which has just come in from outside and
  63. *   check for special sequences that we are interested in.
  64. *
  65. *   Tries to pass through routine strings immediately, waiting for special
  66. *   characters ESC and 255 to change modes.
  67. */
  68.  
  69. void parse (struct WindRec *tw, unsigned char *st, short cnt)
  70. {
  71.     short i,temptw;
  72.     unsigned char *mark,*orig;
  73. #ifdef OPTS_DEBUG
  74.     char munger[255]; 
  75. #endif
  76.     unsigned char *cp;
  77.     char nullbuf[] = {AUTH_NULL, AUTH_CLIENT_TO_SERVER|AUTH_HOW_ONE_WAY};
  78. #ifdef newauth /* (RW) */
  79.     unsigned long sendlength;
  80.     short s;
  81.     unsigned char sendbuffer[1500];
  82. #endif
  83.  
  84.     orig = st;                /* remember beginning point */
  85.     mark = st + cnt;        /* set to end of input string */
  86. /*
  87. * raw mode for debugging, passes through escape sequences and other
  88. * special characters as <27> symbols
  89. */
  90.     if (tw->termstate == DUMBTYPE)
  91.         {
  92.         for (i=0; i < cnt; i++,st++)            /* put on screen raw */
  93.             if (*st == 27 || *st > 126 && !(tw->ftpstate && gFTPServerPrefs->DoISOtranslation))
  94.                 {
  95.                 sprintf((char *)tw->parsedat,"<%d>",*st);
  96.                 VSwrite(tw->vs,(char *)tw->parsedat,strlen((char *)tw->parsedat));    /* send to virtual screen */
  97.                 }
  98.             else
  99.                 VSwrite(tw->vs,(char *) st,1);        /* BYU LSC */
  100.         }
  101.     else
  102.         {
  103.  
  104. /*
  105. *  traverse string, looking for any special characters which indicate that
  106. *  we need to change modes.
  107. */
  108.     while (st < mark) 
  109.         {
  110.         switch (tw->telstate)
  111.             {
  112.             case GS:
  113.             case ESCFOUND:
  114.                 if (tw->tektype >= 0) {    /* we'll allow the TEK */
  115.                     if ((*st == 12) || (tw->telstate == GS)) {    /* esc-FF */
  116.                         if ((*st == 12) && 
  117.                             ((tw->termstate == VTEKTYPE) || (!tw->tekclear))) {
  118.                             if (tw->termstate == VTEKTYPE)
  119.                                 putln("Entering Tek mode");
  120.                             else if (tw->curgraph > -1)
  121.                                 detachGraphics(tw->curgraph);
  122.  
  123.                             if (tw->curgraph <=  -1) {        // No current TEK window
  124.                                 temptw = VGnewwin(1,tw->vs);
  125.  
  126.                                 if (temptw > -1) {
  127.                                     Str255    scratchPstring;
  128.                                     
  129.                                     tw->curgraph = temptw;
  130.     
  131.                                     VGgiveinfo(temptw);
  132.                                     GetWTitle(tw->wind, scratchPstring);
  133.                                     PtoCstr(scratchPstring);
  134.                                     RGattach(temptw,tw->vs,(char *)scratchPstring, tw->tektype);
  135.                                 }
  136.                                 else
  137.                                     tw->telstate = STNORM;  // Can't create TEK window
  138.                             }
  139.  
  140.                             if (tw->telstate != STNORM)
  141.                                 tw->termstate = TEKTYPE;
  142.                         }
  143.  
  144.                         if (tw->telstate == GS) {
  145.                             st++;
  146.                             VGwrite(tw->curgraph,"\035",1);
  147.                         }
  148.                         else if (tw->telstate != STNORM)
  149.                             VGwrite(tw->curgraph,"\037\033\014",3);
  150.  
  151.                         tw->telstate = STNORM;
  152.                         break;
  153.                     } // FF or GS
  154.                 } // tw->tektype >= 0
  155.     
  156.                 if (*st == '^')    {            /* ESC- ^ */
  157.                     tw->termstate = RASTYPE;
  158.                     tw->telstate = STNORM;
  159.                     VRwrite("\033^",2);        /* Put it through */
  160.                     orig = ++st;
  161.                     break;
  162.                 }
  163.                 
  164.                 if (tw->termstate == TEKTYPE)
  165.                     VGwrite(tw->curgraph,"\033",1);
  166.                 else if (tw->termstate  == RASTYPE)
  167.                     VRwrite("\033",1);
  168.                 else
  169.                     VSwrite(tw->vs,"\033",1);    /* send the missing ESC */
  170.                 tw->telstate = STNORM;
  171.                 break;
  172.  
  173.  
  174. /*------------------------------------------------------------------------------*
  175.  *     IACFOUND:  This is the start of the Telnet option negotiation.  If Telnet    *
  176.  *    gets an IAC character, then negotiation data follows, and is ready to be    *
  177.  *     parsed.                                                                     *
  178.  *------------------------------------------------------------------------------*/
  179.             case IACFOUND:         /* telnet option negotiation- START */
  180.                 if (*st == 255) {        /* real data = 255 */
  181.                     orig = st;            // MP: translation mod (break will make it miss
  182.                                         // this assignment later on in the case, Jim!)
  183.                     st++;                /* real 255 will get sent */
  184.                     tw->telstate = STNORM;
  185.                     break;
  186.                 }
  187.                 if ( 239 < *st ) {
  188.                     tw->telstate = *st;        /* by what the option is */
  189.                     st++;
  190.                     break;
  191.                 }
  192.                 tw->telstate = STNORM;
  193.                 orig=st;
  194.                 break;
  195.  
  196.  
  197.             case TEL_EOF:        /* BYU LSC */
  198. #ifdef OPTS_DEBUG
  199.                 sprintf(munger,"RECV: %s",telstates[tw->telstate - TEL_SE]);
  200.                 opts_debug_print(munger); 
  201. #endif
  202.                 orig=st;
  203.                 tw->telstate=STNORM;
  204.                 break;
  205.  
  206.             case TEL_EL:                /* thanx Quincey!!! */
  207.             case TEL_EC:
  208.             case TEL_AYT:
  209.             case TEL_AO:
  210.             case TEL_IP:
  211.             case TEL_BREAK:
  212.             case TEL_DM:
  213.             case TEL_NOP:
  214.             case TEL_SE:
  215. #ifdef OPTS_DEBUG
  216.                 sprintf(munger,"RECV: %s",telstates[tw->telstate - TEL_SE]);
  217.                 opts_debug_print(munger); 
  218. #endif
  219.                 tw->telstate = STNORM;
  220.                 orig=st;
  221.  
  222.  
  223.             case TEL_GA:
  224.                 orig=st;
  225.                 tw->telstate = STNORM;
  226.                 break;
  227.  
  228.  
  229.  
  230. /*------------------------------------------------------------------------------*
  231.  *     Negotiate DOTEL:  sent by the server whenever it wants the client to do     *
  232.  *    an option                                                                    *
  233.  *------------------------------------------------------------------------------*/
  234.             case TEL_DOTEL:
  235. #ifdef OPTS_DEBUG
  236.                 sprintf(munger,"RECV: %s %s",telstates[tw->telstate-TEL_SE],teloptions[*st]);
  237.                 opts_debug_print(munger); 
  238. #endif
  239.                 switch( *st) 
  240.                     {
  241.                     case  N_SGA:        /* Sure we'll supress GA */
  242.                         if (!tw->Isga) {
  243.                             tw->Isga=1;
  244.                             sprintf((char *)tw->parsedat,"%c%c%c",255,TEL_WILLTEL,*st);
  245.                             netpush(tw->port);
  246.                             netwrite(tw->port,tw->parsedat,3);
  247.                             }
  248. #ifdef OPTS_DEBUG
  249.                         sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  250.                         opts_debug_print(munger); 
  251. #endif
  252.                         tw->telstate = STNORM;
  253.                         orig = ++st;
  254.                         break;
  255.                     
  256.                     case N_TERMTYP:        /* And we'll even tell you about ourselves */
  257.                         if (!tw->Ittype) {
  258.                             tw->Ittype=1;
  259.                             sprintf((char *)tw->parsedat,"%c%c%c",255,TEL_WILLTEL,*st);
  260.                             netpush(tw->port);
  261.                             netwrite(tw->port,tw->parsedat,3);
  262.                             }
  263. #ifdef OPTS_DEBUG
  264.                         sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  265.                         opts_debug_print(munger); 
  266. #endif
  267.                         tw->telstate = STNORM;
  268.                         orig = ++st;
  269.                         break;
  270.  
  271.                     case  N_NAWS:            /* NCSA: sure, I like changing the window size! */
  272.                         tw->naws =1;        /* NCSA: this session is now NAWS */
  273.                         sprintf((char *)tw->parsedat,"%c%c%c",255,TEL_WILLTEL,*st);        /* NCSA: reply, we will to NAWS */
  274.                         netpush(tw->port);                                /* NCSA */
  275.                         netwrite(tw->port,tw->parsedat,3);                /* NCSA: send it out */
  276. #ifdef OPTS_DEBUG
  277.                         sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  278.                         opts_debug_print(munger); 
  279. #endif
  280.                         SendNAWSinfo(tw, tw->width, tw->rows);
  281. //                        sprintf((char *)tw->parsedat,"%c%c%c%c%c%c%c%c%c",IAC,TEL_SB,    /* BYU 2.4.16 */
  282. //                            N_NAWS,(char)0,(unsigned char)tw->width,        /* BYU 2.4.16 */
  283. //                            (char)0,(unsigned char)tw->rows,IAC,TEL_SE);    /* BYU 2.4.16 */
  284. //                        netpush(tw->port);                                /* BYU 2.4.16 */
  285. //                        netwrite(tw->port,tw->parsedat,9);                    /* BYU 2.4.16 */
  286. #ifdef OPTS_DEBUG
  287.                         opts_debug_print("SENT: IAC TEL_SB N_NAWS <data> IAC TEL_SE"); 
  288. #endif
  289.  
  290.                         tw->telstate = STNORM;                            /* NCSA */
  291.                         orig = ++st;                                    /* NCSA */
  292.                         break;                                            /* NCSA */
  293.  
  294.                     case N_LINEMODE:  /* Sure I'll do line mode... */
  295.                         if (tw->lineAllow)  {
  296.                             sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WILLTEL,*st++);
  297.                             netwrite(tw->port,tw->parsedat,3);
  298. #ifdef OPTS_DEBUG
  299.                             sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  300.                             opts_debug_print(munger); 
  301. #endif
  302.                             sprintf((char *)tw->parsedat,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  303.                             netwrite(tw->port,tw->parsedat,4);
  304. #ifdef OPTS_DEBUG
  305.                             opts_debug_print("SENT: IAC SB LINEMODE SLC");
  306. #endif    
  307.                             for (i=1; i<= SLC_MAX; i++){
  308.                                 if (tw->slc[i]==-1) {
  309. #ifdef    SEND_NOSUPPORT_ON_SLC_INIT
  310.                                     sprintf((char *)tw->parsedat,"%c%c%c",i,SLC_NOSUPPORT,0);
  311. #ifdef OPTS_DEBUG
  312.                                     sprintf(munger,"     %s NO_SUPPORT 0",LMoptions[i]);
  313. #endif
  314. #endif
  315.                                     }
  316.                                 else
  317.                                     {
  318.                                     sprintf((char *)tw->parsedat,"%c%c%c",i,SLC_CANTCHANGE,(char)tw->slc[i]);
  319.  
  320. #ifdef OPTS_DEBUG
  321.                                     sprintf(munger,"     %s CANTCHANGE %i",LMoptions[i],(int)tw->slc[i]);
  322. #endif
  323.                                     }
  324.                                 opts_debug_print(munger);
  325.                                 netwrite(tw->port,tw->parsedat,3);
  326.                                 }
  327.     
  328.                             opts_debug_print("SENT: IAC SE");
  329.                             sprintf((char *)tw->parsedat,"%c%c",IAC,TEL_SE);
  330.                             netwrite(tw->port,tw->parsedat,2);
  331.                             }
  332.                         else {
  333.                             sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WONTTEL,*st++);
  334.                             opts_debug_print("SENT: WONT Linemode");
  335.                             netwrite(tw->port,tw->parsedat,3);
  336.                             }
  337.                         break;
  338.  
  339.                     case N_AUTHENTICATION:        /* do auth */
  340.                         if (!tw->myopts[OPT_AUTHENTICATION-MHOPTS_BASE]) {
  341.                             if (tw->authenticate) {
  342.                                 (tw->myopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1;
  343.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WILLTEL,*st);
  344.                                 netwrite(tw->port,tw->parsedat,3);
  345. #ifdef OPTS_DEBUG
  346.                                 sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  347.                                 opts_debug_print(munger); 
  348. #endif
  349.                             } else {
  350.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WONTTEL,*st);
  351.                                 netwrite(tw->port,tw->parsedat,3);
  352. #ifdef OPTS_DEBUG
  353.                                 sprintf(munger,"SENT: WONT %s",teloptions[*st]);
  354.                                 opts_debug_print(munger); 
  355. #endif
  356.                             }
  357.                         }
  358.                         tw->telstate = STNORM;
  359.                         orig = ++st;
  360.                         break;
  361.  
  362.                     case N_ENCRYPT:             /* do encrypt */
  363.                         if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) {
  364.                             if (tw->encrypt) {
  365.                                 (tw->myopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1;
  366.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WILLTEL,*st);
  367.                                 netwrite(tw->port,tw->parsedat,3);
  368. #ifdef OPTS_DEBUG
  369.                                 sprintf(munger,"SENT: WILL %s",teloptions[*st]);
  370.                                 opts_debug_print(munger); 
  371. #endif
  372.                             } else {
  373.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_WONTTEL,*st);
  374.                                 netwrite(tw->port,tw->parsedat,3);
  375. #ifdef OPTS_DEBUG
  376.                                 sprintf(munger,"SENT: WONT %s",teloptions[*st]);
  377.                                 opts_debug_print(munger); 
  378. #endif
  379.                             }
  380.                         }
  381.                         tw->telstate = STNORM;
  382.                         orig = ++st;
  383.                         break;
  384.  
  385.                     default:                /* But, we won't do .... */
  386.                         sprintf((char *)tw->parsedat,"%c%c%c",255,TEL_WONTTEL,*st++);
  387.                         netwrite(tw->port,tw->parsedat,3);  
  388. #ifdef OPTS_DEBUG
  389.                         sprintf(munger,"SENT: WONT %s",teloptions[*(st-1)]);
  390.                         opts_debug_print(munger); 
  391. #endif
  392.                         break;
  393.                     }
  394.                 tw->telstate = STNORM;
  395.                 orig = st;
  396.                 break;
  397.  
  398.  
  399. /*------------------------------------------------------------------------------*
  400.  *     Negotiate DONTTEL:  sent by the server whenever it wants the client to      *
  401.  *    definitely NOT do an option.  Sent to prevent client from negotiating an    *
  402.  *    unsupported option                                                            *
  403.  *------------------------------------------------------------------------------*/
  404.             case TEL_DONTTEL:
  405. #ifdef OPTS_DEBUG
  406.                 sprintf(munger,"RECV: %s %s",telstates[tw->telstate-TEL_SE],teloptions[*st]);
  407.                 opts_debug_print(munger); 
  408. #endif
  409.                 tw->telstate = STNORM;
  410.                 switch (*st++) {
  411.                     case N_ENCRYPT:                    /* dont encrypt */
  412.                     case N_AUTHENTICATION:            /* dont authenticate */
  413.                         tw->myopts[*(st-1)-MHOPTS_BASE] = 0;
  414.                         sprintf((char *)tw->parsedat,"%c%c%c", IAC, TEL_WONTTEL, *(st-1));
  415.                         netpush(tw->port);
  416.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  417. #ifdef OPTS_DEBUG
  418.                         sprintf(munger,"SENT: WONT %s", teloptions[*(st-1)]);
  419.                         opts_debug_print(munger); 
  420. #endif    
  421.                         break;
  422.                 }
  423.                 orig = st;
  424.                 break;
  425.  
  426.  
  427. /*------------------------------------------------------------------------------*
  428.  *     Negotiate WILLTEL:  sent by the client to try and get the server to use an    *
  429.  *    option.  This tells the server that the client is requesting that an option *
  430.  *     be used                                                                        *
  431.  *------------------------------------------------------------------------------*/
  432.             case TEL_WILLTEL:
  433. #ifdef OPTS_DEBUG
  434.                 sprintf(munger,"RECV: %s %s",telstates[tw->telstate-TEL_SE],teloptions[*st]);
  435.                 opts_debug_print(munger); 
  436. #endif
  437.                 tw->telstate = STNORM;
  438.                 switch(*st++) 
  439.                     {
  440.                     case N_ECHO:             /* Echo on the other end*/
  441. #ifdef    OPTS_DEBUG
  442.                         if (!tw->echo)
  443.                             opts_debug_print("tw->echo is False.");
  444. #endif
  445.                         if (!tw->echo)
  446.                             break;
  447.                         tw->echo = 0;    /* Ok, in that case they can echo... */
  448.                         changeport(scrn,scrn);
  449.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DOTEL,1);
  450.                         netpush(tw->port);
  451.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  452. #ifdef OPTS_DEBUG
  453.                         sprintf(munger,"SENT: DO %s",teloptions[*(st-1)]);
  454.                         opts_debug_print(munger); 
  455. #endif
  456.                         break;
  457.                     
  458.                     case N_SGA:                /* Supress GA */
  459. #ifdef    OPTS_DEBUG
  460.                         if (tw->Usga)
  461.                             opts_debug_print("tw->Usga is True.");
  462. #endif
  463.                         if (tw->Usga)
  464.                             break;
  465.                         tw->Usga = 1;    /* Go Ahead and supress GA */
  466.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DOTEL,3);
  467.                         netpush(tw->port);
  468.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  469. #ifdef OPTS_DEBUG
  470.                         sprintf(munger,"SENT: DO %s",teloptions[*(st-1)]);
  471.                         opts_debug_print(munger); 
  472. #endif
  473.                         break;
  474.                     
  475.                     case N_TIMING:                /* Timing Mark */
  476.                         tw->timing = 0;
  477.                         break;
  478.                     
  479.                     case N_AUTHENTICATION:        /* will auth */
  480.                         if (!tw->hisopts[OPT_AUTHENTICATION-MHOPTS_BASE]) {
  481.                             if (tw->authenticate) {
  482.                                 (tw->hisopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1;
  483.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DOTEL,OPT_AUTHENTICATION);
  484.                                 netwrite(tw->port,tw->parsedat,3);
  485. #ifdef OPTS_DEBUG
  486.                                 sprintf(munger,"SENT: WILL %s",teloptions[OPT_AUTHENTICATION]);
  487.                                 opts_debug_print(munger); 
  488. #endif
  489.                             } else {
  490.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,OPT_AUTHENTICATION);
  491.                                 netwrite(tw->port,tw->parsedat,3);
  492. #ifdef OPTS_DEBUG
  493.                                 sprintf(munger,"SENT: WONT %s",teloptions[OPT_AUTHENTICATION]);
  494.                                 opts_debug_print(munger); 
  495. #endif
  496.                             }
  497.                         }
  498.                         break;
  499.  
  500.                     case N_ENCRYPT:             /* will encrypt */
  501.                         if (!tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE]) {
  502.                             if (tw->encrypt) {
  503.                                 (tw->hisopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1;
  504.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DOTEL,OPT_ENCRYPT);
  505.                                 netwrite(tw->port,tw->parsedat,3);
  506. #ifdef OPTS_DEBUG
  507.                                 sprintf(munger,"SENT: DO %s",teloptions[OPT_ENCRYPT]);
  508.                                 opts_debug_print(munger); 
  509. #endif
  510.                             } else {
  511.                                 sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,OPT_ENCRYPT);
  512.                                 netwrite(tw->port,tw->parsedat,3);
  513. #ifdef OPTS_DEBUG
  514.                                 sprintf(munger,"SENT: DONT %s",teloptions[OPT_ENCRYPT]);
  515.                                 opts_debug_print(munger); 
  516. #endif
  517.                             }
  518.                         }
  519.  
  520. #ifndef newauth /* (RW) */
  521.                         if (tw->authenticate && tw->encrypt)    /* do this here (and tn3270?) ddd */
  522.                             encrypt_send_support(tw->edata);
  523. #endif
  524.                         break;
  525.  
  526.                     default:
  527.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,*(st-1));
  528.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  529. #ifdef OPTS_DEBUG
  530.                         sprintf(munger,"SENT: DONT %s",teloptions[*(st-1)]);
  531.                         opts_debug_print(munger); 
  532. #endif
  533.                     }
  534.                 orig = st;
  535.                 break;
  536.  
  537.  
  538.  
  539. /*------------------------------------------------------------------------------*
  540.  *     Negotiate WONTTEL:  The client refuses a Telnet option, and wants the         *
  541.  *    to forget about trying to negotiate it.                                        *
  542.  *------------------------------------------------------------------------------*/
  543.             case TEL_WONTTEL:
  544. #ifdef OPTS_DEBUG
  545.                 sprintf(munger,"?SENT: (WONTTEL)%s %s",telstates[tw->telstate-TEL_SE],teloptions[*st]);
  546.                 opts_debug_print(munger); 
  547. #endif
  548.                 tw->telstate = STNORM;
  549.                 switch(*st++) 
  550.                     {         /* which option? */
  551.                     case N_ECHO:             /* echo */
  552.                         if (tw->echo)
  553.                             break;
  554.                         tw->echo = 1;    /* Ok, I will echo if I have to... */
  555.                         changeport(scrn,scrn);
  556.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,N_ECHO);
  557.                         netpush(tw->port);
  558.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  559. #ifdef OPTS_DEBUG
  560.                         sprintf(munger,"SENT: %s %s",telstates[TEL_WONTTEL-TEL_SE],teloptions[*(st-1)]);
  561.                         opts_debug_print(munger); 
  562. #endif    
  563.                         break;
  564.                     
  565.                     case N_SGA:
  566.                         if (!tw->Usga)
  567.                             break;
  568.                         tw->Usga = 0;
  569.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,N_SGA);
  570.                         netpush(tw->port);
  571.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  572. #ifdef OPTS_DEBUG
  573.                         sprintf(munger,"SENT: %s %s",telstates[TEL_WONTTEL-TEL_SE],teloptions[*(st-1)]);
  574.                         opts_debug_print(munger); 
  575. #endif    
  576.                         break;
  577.                     
  578.                     case N_TIMING:                /* Timing Mark */
  579.                         tw->timing = 0;
  580.                         break;
  581.                     
  582.                     case N_ENCRYPT:                    /* wont encrypt */
  583.                     case N_AUTHENTICATION:            /* wont authenticate */
  584.                         tw->hisopts[*(st-1)-MHOPTS_BASE] = 0;
  585.                         sprintf((char *)tw->parsedat,"%c%c%c",IAC,TEL_DONTTEL,*(st-1));
  586.                         netpush(tw->port);
  587.                         netwrite(tw->port,tw->parsedat,3);  /* refuse it */
  588. #ifdef OPTS_DEBUG
  589.                         sprintf(munger,"SENT: WONT %s", teloptions[*(st-1)]);
  590.                         opts_debug_print(munger); 
  591. #endif    
  592.                         break;
  593.  
  594.                     default:
  595.                         break;
  596.                     }
  597.                 orig = st;
  598.                 break;
  599.  
  600.  
  601.  
  602. /*------------------------------------------------------------------------------*
  603.  *     SUBNEGOTIATION -- If there is an SB token found, then Telnet needs to do     *
  604.  *    some subnegotiating.  The subnegotiation data follows, and needs to be put    *
  605.  *    somewhere safe.  Make sure and update the state, so that we know that        *
  606.  *    Telnet is doing some subnegotiations and not just horsing around            *
  607.  *------------------------------------------------------------------------------*/
  608.             case TEL_SB:
  609.                 tw->telstate = NEGOTIATE;        /* Guess what I'm doing... */
  610.                 orig=st;
  611.                 substate=0;                /* Defined for each */
  612.                 tw->parseIndex =0;        /* No data yet! Clear any possible garbage */
  613.                 break;
  614.  
  615.             case NEGOTIATE:
  616.                 if (substate <200) {
  617.                     switch( *st) {
  618.                         case IAC:                /* is it the famous DOUBLE-IAC??? */
  619.                             if (*(st+1) ==IAC)     /* Yes, treat as data value 255 */
  620.                                 {
  621.                                 tw->parsedat[tw->parseIndex++]=*st++;
  622.                                 /*tw->parsedat[tw->parseIndex++]=* */ st++;
  623.                                 }
  624.                             else                 /* otherwise just save it */
  625.                                 {
  626.                                 tw->parsedat[tw->parseIndex]='\0';
  627.                                 substate=*st++;
  628.                                 }                            
  629.                             break;
  630.                         default:
  631.                             tw->parsedat[tw->parseIndex++]=*st++;
  632.                             break;
  633.                         }
  634.                     } else 
  635.                     
  636.                     {
  637.                     switch( substate)     /* subnegotiate */
  638.                         {
  639.                         case IAC:
  640.                             substate=*st++;
  641.                             if (substate==TEL_SE) {
  642.                                 switch( tw->parsedat[0]) 
  643.                                     {
  644. /*------------------------------------------------------------------------------*
  645.  *     SUBNegotiate Termtype:  send the term type data now                            *
  646.  *------------------------------------------------------------------------------*/
  647.                                     case N_TERMTYP:            
  648.                                         if (tw->parsedat[1]==1) 
  649.                                             {
  650.                                             char s[255], termtmp[40];
  651.                                             BlockMove(tw->answerback, termtmp, 32);
  652.                                             PtoCstr((StringPtr)termtmp);
  653.     #ifdef OPTS_DEBUG
  654.                                             sprintf(munger,"RECV: SB TERMINAL-TYPE SEND\r\nSEND: SB TERMINAL-TYPE IS %s\r\n",termtmp);
  655.                                             opts_debug_print(munger); 
  656.     #endif
  657.                                             netpush(tw->port);
  658.                                             netwrite(tw->port,"\377\372\030\000",4);
  659.                                             netpush(tw->port);
  660.                                             sprintf(s,"%s\377\360",termtmp);
  661.                                             netwrite(tw->port, s, strlen(s));
  662.                                             }
  663.                                         break;
  664.                                         
  665. /*------------------------------------------------------------------------------*
  666.  *     SUBNegotiate ENCRYPTION:                                                     *
  667.  *------------------------------------------------------------------------------*/
  668.                                     case N_ENCRYPT:    {
  669. #ifdef newauth                            /* (RW) */
  670.                                         sendlength = sizeof(sendbuffer);
  671.                                         s = encrypt_suboption((tnParams **)&tw->aedata, tw->parsedat,
  672.                                                               tw->parseIndex,
  673.                                                               sendbuffer, &sendlength, getcname(tw), 
  674.                                                               tw->hisopts[OPT_ENCRYPT - MHOPTS_BASE], 
  675.                                                               tw->myopts[OPT_ENCRYPT - MHOPTS_BASE]);
  676.                                         netportencryptstate(tw->port, (Ptr)tw->aedata);
  677.                                         encryptStatechange(tw);
  678.  
  679.                                         /*
  680.                                          * If we turned on encryption, we must decrypt the rest of the buffer.
  681.                                          */
  682.                                         if (s == TNREP_START_DECRYPT) {
  683.                                             unsigned char *cp = st;
  684.                                             while (cp < mark) {
  685.                                                 *cp = decrypt((tnParams *)tw->aedata, (long)(*cp));
  686.                                                 cp++;
  687.                                             }
  688.                                         }
  689.  
  690.                                         if (sizeof(sendbuffer) - sendlength)
  691.                                             netwrite(tw->port, sendbuffer, sizeof(sendbuffer)-sendlength);
  692.                                         
  693.                                         /*
  694.                                          * transfer the encrypting flag here, after the buffer with encrypt-start has
  695.                                          * gone out.
  696.                                          */
  697.                                         if (((tnParams *)tw->aedata)->startencrypting) {
  698.                                             ((tnParams *)tw->aedata)->startencrypting = false;
  699.                                             ((tnParams *)tw->aedata)->encrypting = true;
  700.                                         }
  701. #else /* newauth */
  702.  
  703.                                         unsigned char *subpointer = &tw->parsedat[SB_TYPE];
  704.                                         long    sublen = &tw->parsedat[tw->parseIndex] - 
  705.                                             subpointer;
  706. #ifdef OPTS_DEBUG
  707.                                         {
  708.                                             short    j;
  709.                                             char *cp = munger;
  710.  
  711.                                             sprintf(cp,"RECV: SB ENCRYPT %02X ",
  712.                                                     tw->parsedat[SB_SUBOPTION]);
  713.                                             cp += strlen(cp);
  714.                                             for (j = 0; j < sublen; j++) {
  715.                                                 sprintf(cp, "%02X ", subpointer[j] & 0xff);
  716.                                                 cp += strlen(cp);
  717.                                             }
  718.                                             sprintf(cp, "\r\n");
  719.                                             opts_debug_print(munger); 
  720.                                         }
  721. #endif
  722.                                          if (tw->edata != NULL)
  723.                                             netportencryptstate(tw->port, (Ptr)tw->edata);
  724.                                         switch (tw->parsedat[SB_SUBOPTION]) {
  725.                                         case ENCRYPT_START:
  726.                                             if (!tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE])     /* my_want_state_is_dont(tw->o_encrypt) */
  727.                                                 break;
  728.                                             encrypt_start(tw->edata, subpointer, sublen);
  729.                                             /*
  730.                                              * If we turned on decryption we must
  731.                                              * decrypt the remainder of the buffer
  732.                                              */
  733.                                             if (tw->edata->decrypt_input) {
  734.                                                 unsigned char *cp = st;
  735.                                                 while (cp < mark) {
  736.                                                     *cp = (*tw->edata->decrypt_input)(tw->edata, (int)(*cp));
  737.                                                     cp++;
  738.                                                 }
  739.                                                  netportencryptstate(tw->port, (Ptr)tw->edata);
  740.                                             }
  741.                                             break;
  742.  
  743.                                         case ENCRYPT_END:
  744.                                             if (!tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE]) /* if my_want_state_is_dont(tw->o_encrypt) */
  745.                                             break;
  746.                                             encrypt_end(tw->edata);
  747.                                             break;
  748.  
  749.                                         case ENCRYPT_SUPPORT:
  750.                                             if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) /* if my_want_state_is_wont(tw->o_encrypt) */
  751.                                                 break;
  752.                                             encrypt_support(tw->edata, subpointer, sublen);
  753.                                             break;
  754.  
  755.                                         case ENCRYPT_REQSTART:
  756.                                         if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) /* if my_want_state_is_wont(tw->o_encrypt) */
  757.                                             break;
  758.                                             encrypt_request_start(tw->edata, subpointer, sublen);
  759.                                             break;
  760.  
  761.                                         case ENCRYPT_REQEND:
  762.                                             if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) /* if my_want_state_is_wont(tw->o_encrypt) */
  763.                                                 break;
  764.                                             /*
  765.                                              * We can always send an REQEND so that 
  766.                                              * we cannot get stuck encrypting.  We 
  767.                                              * should only get this if we have been 
  768.                                              * able to get in the correct mode
  769.                                              * anyhow.
  770.                                              */
  771.                                             encrypt_request_end(tw->edata);
  772.                                             break;
  773.                                         case ENCRYPT_IS:
  774.                                             if (!tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE]) /* if my_want_state_is_dont(tw->o_encrypt) */
  775.                                                 break;
  776.                                             encrypt_is(tw->edata, subpointer, sublen);
  777.                                             break;
  778.                                         case ENCRYPT_REPLY:
  779.                                             if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) /* if my_want_state_is_wont(tw->o_encrypt) */
  780.                                                 break;
  781.                                             encrypt_reply(tw->edata, subpointer, sublen);
  782.                                             break;
  783.                                         case ENCRYPT_ENC_KEYID:
  784.                                             if (!tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE]) /* if my_want_state_is_dont(tw->o_encrypt) */
  785.                                                 break;
  786.                                             encrypt_enc_keyid(tw->edata, subpointer, sublen);
  787.                                             break;
  788.                                         case ENCRYPT_DEC_KEYID:
  789.                                             if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) /* if my_want_state_is_wont(tw->o_encrypt) */
  790.                                                 break;
  791.                                             encrypt_dec_keyid(tw->edata, subpointer, sublen);
  792.                                             break;
  793.                                         default:
  794.                                             break;
  795.                                         }
  796. #endif /* newauth */
  797.                                     }
  798.                                     break;
  799.  
  800. /*------------------------------------------------------------------------------*
  801.  *     SUBNegotiate Authentication:  send the authentication data now                 *
  802.  *------------------------------------------------------------------------------*/
  803.                                     case N_AUTHENTICATION:            
  804. #ifdef newauth                            /* (RW) */
  805.                                         sendlength = sizeof(sendbuffer);
  806.                                         auth_suboption((tnParams **)&tw->aedata, tw->parsedat,
  807.                                                        tw->parseIndex,
  808.                                                        sendbuffer, &sendlength, getcname(tw), 
  809.                                                        tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE], 
  810.                                                        tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]);
  811.                                         if (sizeof(sendbuffer) - sendlength)
  812.                                             netwrite(tw->port, sendbuffer, sizeof(sendbuffer)-sendlength);
  813. #else /* newauth */
  814.  
  815. #ifdef OPTS_DEBUG2
  816.                                         {
  817.                                             short    j;
  818.                                             char    *cp = munger;
  819.                                             char    *subpointer = &tw->parsedat[SB_TYPE];
  820.                                             long    sublen = &tw->parsedat[tw->parseIndex] - 
  821.                                                 subpointer;
  822.  
  823.                                             sprintf(cp,"RECV: SB AUTH %02X ",
  824.                                                     tw->parsedat[SB_SUBOPTION]);
  825.                                             cp += strlen(cp);
  826.                                             for (j = 0; j < sublen; j++) {
  827.                                                 sprintf(cp, "%02X ", subpointer[j] & 0xff);
  828.                                                 cp += strlen(cp);
  829.                                             }
  830.                                             sprintf(cp, "\r\n");
  831.                                             opts_debug_print(munger); 
  832.                                         }
  833. #endif
  834.                                         switch (tw->parsedat[SB_SUBOPTION]) {
  835.                                         case TNQ_IS:
  836.                                             break;
  837.  
  838.                                         case TNQ_SEND:
  839.                                             /*
  840.                                              * For telnet clients.
  841.                                              * The buffer contains:
  842.                                              * AUTHENTICATION SEND type modifier 
  843.                                              *        [type modifier] [...]
  844.                                              * Scan the type/modifier pairs until we 
  845.                                              * find one we can do. Since they are are 
  846.                                              * in priority order, the  first one we
  847.                                              * find that we can do wins.
  848.                                              */
  849.                                             cp = &tw->parsedat[SB_TYPE];
  850.                                             for (; cp < &tw->parsedat[tw->parseIndex]; 
  851.                                                                     cp += 2) {
  852.                                                 switch (*cp) {
  853.                                                 case AUTH_KERBEROS_V4:
  854.                                                     if (krb_telnet(tw, (char *)cp, true)) {
  855.                                                         /*
  856.                                                          * if krb_telnet fails, send null authentication
  857.                                                          * to avoid hanging.
  858.                                                          */
  859.                                                         tn_sendsub(tw, N_AUTHENTICATION, TNQ_IS, 
  860.                                                                        nullbuf, sizeof(nullbuf));
  861.                                                     }                                                                        
  862.                                                     goto xx1;
  863.                                                 }
  864.                                             }
  865.                                             /*
  866.                                              * If we can't do any of the requested 
  867.                                              * authorizations, send AUTH_NULL.
  868.                                              */
  869.                                             tn_sendsub(tw, N_AUTHENTICATION, TNQ_IS, 
  870.                                                        nullbuf, sizeof(nullbuf));
  871.                                             xx1:
  872.                                             break;
  873.  
  874.                                         case TNQ_REPLY:
  875.                                             /*
  876.                                              * This is a reply to information we sent 
  877.                                              * in a previous IS AUTH or CHALLENGE 
  878.                                              * command. The buffer contains:
  879.                                              * AUTHENTICATION REPLY type modifier 
  880.                                              *       auth-data-type [auth data bytes]
  881.                                              */
  882.                                             switch (tw->parsedat[SB_TYPE] & 0xFF) {
  883.                                             case AUTH_KERBEROS_V4:
  884.                                                 tn_kerberos_reply(tw, (unsigned char *)tw->parsedat);
  885.                                                 break;
  886.                                             default:
  887.                                                 ;
  888.                                                 /* should we do somthing with an 
  889.                                                    unknown reply type ddd */
  890.                                             }
  891.                                             break;
  892.  
  893.                                         case TNQ_NAME:
  894.                                             /*
  895.                                              * For the telnet server. This is the 
  896.                                              * name that the telnet client
  897.                                              * wants us to use.
  898.                                              */
  899.                                             break;
  900.                                         } /* switch tw->parsedat[SB_SUBOPTION] */
  901. #endif /* newauth */
  902.                                         break;
  903.                                         
  904. /*------------------------------------------------------------------------------*
  905.  *     SUBNegotiate Linemode:  set up local characters, modes, and such            *
  906.  *------------------------------------------------------------------------------*/
  907.                                     case N_LINEMODE:
  908.                                         switch(tw->parsedat[1])
  909.                                             {
  910.                                             char s[80];
  911.  
  912.                                             case L_MODE:    /* change mode */
  913. #ifdef OPTS_DEBUG
  914.                                                 strcpy(s, "RECV: SB LINEMODE MODE => ");
  915.                                                 DemangleLineModeShort(s, tw->parsedat[2]);
  916.                                                 opts_debug_print(s);
  917. #endif
  918.                                                 if (tw->lineAllow) {            // First make sure we allowed linemode in the first place.
  919.                                                     // RFC 1184 says client should ignore MODE negotiations with the MODE_ACK bit set, and should not
  920.                                                     //    generate a response if the negotiated MODE matches the current MODE
  921.                                                     if (!((tw->parsedat[2] & L_MODE_ACK) || ((tw->parsedat[2] & L_MODE_MASK) == tw->lmode))) {
  922.                                                     
  923.                                                         // This is a hack.  Accept the state of L_EDIT and L_TRAPSIG that the server wants.  If
  924.                                                         // the server only wants zero, one, two or both of those bits, generate an ack.  Otherwise
  925.                                                         // send the server a mode that masks out all requested bits except EDIT and TRAPSIG.
  926.                                                         
  927.                                                         // (Now, since we only support L_EDIT and/or L_TRAPSIG, if those are the only modes requested,)
  928.                                                         //    (send an ACK of that MODE to the server.)
  929.                                                         
  930.                                                         tw->lmode = (tw->parsedat[2] & (L_EDIT | L_TRAPSIG));    // Accept the mode.
  931.                                                         
  932.                                                         if ((tw->parsedat[2] & (L_EDIT | L_TRAPSIG)) == tw->parsedat[2]) {
  933.                                                             tw->parsedat[2] |= L_MODE_ACK;    // Set the MODE_ACK bit
  934.                                                             }
  935.                                                         // We got a MODE bit we dont support, mask out just what we support and send it back, UNacked.
  936.                                                         else {
  937.                                                             tw->parsedat[2] = tw->parsedat[2] & (L_EDIT | L_TRAPSIG);
  938.                                                             }
  939.  
  940.                                                         sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_MODE);
  941.                                                         netwrite(tw->port,s,4);
  942.                                                         sprintf(s,"%c%c%c",tw->parsedat[2],IAC,TEL_SE);
  943.                                                         netwrite(tw->port,s,3); 
  944. #ifdef OPTS_DEBUG
  945.                                                         opts_debug_print("SENT: IAC SB");
  946.                                                         strcpy(s, "SENT: LM MODE = ");
  947.                                                         DemangleLineModeShort(s, tw->parsedat[2]);
  948.                                                         opts_debug_print(s);
  949.                                                         opts_debug_print("SENT: IAC SE");
  950. #endif
  951.                                                     }
  952. #ifdef OPTS_DEBUG
  953.                                                     else {
  954.                                                         strcpy(s, "LINEMODE MODE = ");
  955.                                                         DemangleLineModeShort(s, tw->parsedat[2]);
  956.                                                         opts_debug_print(s);
  957.                                                         if (tw->parsedat[2] & L_MODE_ACK) 
  958.                                                             opts_debug_print("\tignored 'cause MODE_ACK was set.");
  959.                                                         else
  960.                                                             opts_debug_print("\tIMPLICITLY ACCEPTED.");
  961.                                                         strcpy(s, "Curr Linemode = ");
  962.                                                         DemangleLineModeShort(s, tw->lmode);
  963.                                                         opts_debug_print(s);
  964.                                                     }
  965. #endif
  966.                                                     
  967.                                                 }
  968.                                                 break;
  969.                                             
  970.                                             case TEL_DOTEL:    
  971. #ifdef OPTS_DEBUG
  972.                                                 sprintf(munger,"RECV: SB LINEMODE DO %c", tw->parsedat[2]);
  973.                                                 opts_debug_print(munger);
  974. #endif
  975.                                                 netwrite(tw->port,"\377\372\042",3);
  976.                                                 sprintf(s,"%c\002\377\360",TEL_WONTTEL);
  977.                                                 opts_debug_print("SENT: IAC SB LINEMODE WONT FORWARDMASK IAC SE");
  978.                                                 netwrite(tw->port,s,strlen(s));
  979.                                                 break;
  980.  
  981.                                             case TEL_WILLTEL:
  982. #ifdef OPTS_DEBUG
  983.                                                 sprintf(munger,"RECV: SB LINEMODE WILL %c", tw->parsedat[2]);
  984.                                                 opts_debug_print(munger);
  985. #endif
  986.                                                 netwrite(tw->port,"\377\372\042",3);
  987.                                                 sprintf(s,"%c\002\377\360",TEL_DONTTEL);
  988.                                                 opts_debug_print("SENT: IAC SB LINEMODE DONT FORWARDMASK IAC SE");
  989.                                                 netwrite(tw->port,s,strlen(s));
  990.                                                 break;
  991.  
  992.  
  993.                                             case L_SLC:        /* set local chars */
  994.                                                 {
  995.                                                 short    lmslcflag = 0;
  996. #ifdef OPTS_DEBUG
  997.                                                 sprintf(munger,"RECV: SB LINEMODE SLC");
  998.                                                 opts_debug_print(munger);
  999.                                                 for(i=2;(tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3) {
  1000.                                                     if(tw->parsedat[i+1] & SLC_AWK)
  1001.                                                         sprintf(munger,"     %s %s|AWK %d",LMoptions[tw->parsedat[i]],LMflags[tw->parsedat[i+1] & SLC_LEVELBITS],tw->parsedat[i+2]);
  1002.                                                     else
  1003.                                                         sprintf(munger,"     %s %s %d",LMoptions[tw->parsedat[i]],LMflags[tw->parsedat[i+1] & SLC_LEVELBITS],tw->parsedat[i+2]);
  1004.                                                     opts_debug_print(munger);
  1005.                                         // 2.6b16.1            if ((unsigned char)(tw->parsedat[i+2])==IAC) i++;
  1006.                                                     }    /* end for */
  1007. #endif
  1008.  
  1009.                                                 for (i=2, lmslcflag=0; (tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3) {
  1010.  
  1011.                                                     // If func = 0, skip it 'cause we are the client.
  1012. //                                                    if (tw->parsedat[i] == 0)
  1013. //                                                        continue;
  1014.                                                     
  1015.                                                     // If it's a function we don't know about, say we don't support it.  If the server is telling
  1016.                                                     // us he doesn't support it, just ignore him.
  1017.                                                     if (tw->parsedat[i] > SLC_MAX) {
  1018.                                                         if ((tw->parsedat[i+1] & SLC_LEVELBITS) != SLC_NOSUPPORT) {
  1019.                                                             if (!lmslcflag) {
  1020.                                                                 lmslcflag = 1;        // Do this only once
  1021.                                                                 sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  1022.                                                                 netwrite(tw->port,s,4);
  1023.                                                                 opts_debug_print("SENT: IAC SB LINEMODE SLC");
  1024.                                                                 }
  1025.                                                             sprintf(s,"%c%c%c",tw->parsedat[i],SLC_NOSUPPORT,0);
  1026. #ifdef OPTS_DEBUG
  1027.                                                             sprintf(munger,"     %d SLC_NOSUPPORT 0",tw->parsedat[i]);
  1028.                                                             opts_debug_print(munger);
  1029. #endif
  1030.                                                             netwrite(tw->port,s,3);
  1031.                                                         }
  1032.                                                         else
  1033.                                                             continue;
  1034.                                                     }
  1035.                                                     
  1036.                                                     // RFC 1184: If we get a response that is the same as the current setting, ignore it.  Technically, we
  1037.                                                     //    should check the value for a CANTCHANGE response to satisfy part 2 of Sec 5.5.  However, since we
  1038.                                                     //    advertised that key as CANTCHANGE in the first place, the server should not be changing it.  This
  1039.                                                     //    should be fixed later, however I don't see it causing big problems right now. - JMB 12/93
  1040.                                                     
  1041.                                                     if (! ((((tw->parsedat[i+1] & SLC_LEVELBITS) == SLC_NOSUPPORT) && (tw->slc[tw->parsedat[i]] == -1))
  1042.                                                         || (((tw->parsedat[i+1] & SLC_LEVELBITS) == SLC_CANTCHANGE) && (tw->slc[tw->parsedat[i]] != -1)))) {
  1043.                                                         // If we get to this point, the value sent to us doesn't agree with what we want.
  1044.                                                         
  1045.                                                             
  1046.                                                         if (!(tw->parsedat[i+1] & SLC_AWK)) {
  1047.                                                             if (!lmslcflag) {
  1048.                                                                 lmslcflag = 1;        // Do this only once
  1049.                                                                 sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  1050.                                                                 netwrite(tw->port,s,4);
  1051.                                                                 opts_debug_print("SENT: IAC SB LINEMODE SLC");
  1052.                                                                 }
  1053.                                                         
  1054.                                                             if (tw->slc[tw->parsedat[i]]==-1)
  1055.                                                                 {
  1056.                                                                 sprintf(s,"%c%c%c",tw->parsedat[i],SLC_NOSUPPORT,0);
  1057. #ifdef OPTS_DEBUG
  1058.                                                                 sprintf(munger,"     %s SLC_NOSUPPORT 0",LMoptions[tw->parsedat[i]]);
  1059. #endif
  1060.                                                                 }
  1061.                                                             else
  1062.                                                                 {
  1063.                                                                 sprintf(s,"%c%c%c",tw->parsedat[i],SLC_CANTCHANGE,(char)tw->slc[tw->parsedat[i]]);
  1064. #ifdef OPTS_DEBUG
  1065.                                                                 sprintf(munger,"     %s SLC_CANTCHANGE %d",LMoptions[tw->parsedat[i]],
  1066.                                                                                             (char)tw->slc[tw->parsedat[i]]);
  1067. #endif
  1068.                                                                 }                                                                
  1069. #ifdef OPTS_DEBUG
  1070.                                                             opts_debug_print(munger);
  1071. #endif
  1072.                                                             netwrite(tw->port,s,3);
  1073.                                         // 2.6b16.1                    if (tw->parsedat[i+2]==IAC) i++;
  1074.                                                             }
  1075.                                                         }
  1076.                                                     }
  1077.                                                     
  1078.                                                 if (lmslcflag) {
  1079.                                                     sprintf(s,"%c%c",IAC,TEL_SE);
  1080.                                                     netwrite(tw->port,s,2);
  1081.                                                     }
  1082.                                                     
  1083.  
  1084.                                                     /* otherwise just exit */
  1085.                                                     }
  1086.                                                     break;
  1087.                                                 
  1088.                                                 default:
  1089. #ifdef OPTS_DEBUG
  1090.                                                     sprintf(munger, "RECV: SB LINEMODE ?? (?? = %c)", tw->parsedat[1]);
  1091.                                                     opts_debug_print(munger);
  1092. #endif
  1093.                                                     break;
  1094.  
  1095.                                                 }
  1096.                                         break;
  1097.  
  1098. /* end of all the new line-mode stuff */                                
  1099.                                 
  1100.                                 
  1101.                                 default:
  1102.                                     break;
  1103.                                 }
  1104.                             } // substate == TEL_SE
  1105.                             orig=st;
  1106.                             tw->telstate=STNORM;
  1107.                             break;
  1108.                         default:
  1109.                             orig=st;
  1110.                             tw->telstate=STNORM;
  1111.                             break;
  1112.                         } // switch(substate)
  1113.                     }
  1114.  
  1115.                 break;
  1116.             default:
  1117.                 tw->telstate = STNORM;
  1118.                 break;
  1119.         } // switch(tw->telstate)
  1120.  
  1121. /*
  1122. * quick scan of the remaining string, skip chars while they are
  1123. * uninteresting
  1124. */
  1125.         if (tw->telstate == STNORM) {
  1126. /*
  1127. *  skip along as fast as possible until an interesting character is found
  1128. */
  1129.  
  1130.             if (!tw->eightbit) {                                            /* BYU 2.4.10 */
  1131.                 while (st < mark) {                                            /* BYU 2.4.10 */
  1132.                     if (*st == IAC)                                         /* BYU 2.4.10 */
  1133.                         break;                                                /* BYU 2.4.10 */
  1134.                     else {                                                    /* BYU 2.4.10 */
  1135.                         *st &= 0x7f;                                         /* BYU 2.4.10 */
  1136.                         if (*st == ESC  || *st == GS)                         /* BYU 2.4.10 */
  1137.                             break;                                            /* BYU 2.4.10 */
  1138.                         st++;                                                /* BYU 2.4.10 */
  1139.                 }    }                                                        /* BYU 2.4.10 */
  1140.             } else                                                             /* BYU 2.4.10 */
  1141.                 while (st < mark && *st != ESC  && *st < 255 && *st != GS)     // MP: translation mod
  1142.                     st++;                                                     /* BYU 2.4.10 */
  1143. /*
  1144. *  send the string where it belongs
  1145. */
  1146.             if (!tw->timing) {
  1147.                 if (tw->termstate == TEKTYPE) {
  1148.                     short i;
  1149.                     
  1150.                     i = VGwrite( tw->curgraph,(char *) orig,  st-orig);    /* BYU LSC */
  1151.                     if (i < (st - orig)) {
  1152.                         detachGraphics(tw->curgraph);
  1153.                         st = orig + i;
  1154.                         }
  1155.                     }
  1156.                 else if (tw->termstate == RASTYPE) {
  1157.                     short i;
  1158.                     
  1159.                     i= VRwrite((char *) orig, st-orig);        /* BYU LSC */
  1160.                     if (i <(st-orig)) {
  1161.                         tw->termstate = VTEKTYPE;
  1162.                         st = orig +i;                /* Next char to parse */
  1163.                         }
  1164.                     }
  1165.                 else 
  1166.                     VSwrite( tw->vs,(char *) orig,st-orig);    /* BYU LSC - send to virtual VT102 */
  1167.                 }
  1168.  
  1169.             orig = st;                /* forget what we have sent already */
  1170.  
  1171.             if (st < mark)
  1172.                 switch (*st) {
  1173.                     case 255:            /* telnet IAC */
  1174.                         tw->telstate = IACFOUND;
  1175.                         st++;
  1176.                         break;
  1177.                     case GS:
  1178.                         if (tw->telstate != GS) {
  1179.                             tw->telstate = GS;
  1180.                             }
  1181.                         else
  1182.                             tw->telstate = STNORM;
  1183.                         st++;
  1184.                         break;
  1185.                         
  1186.                     case ESC:            /* ESCape code */
  1187.                         if (st == mark-1 || *(st+1) == 12 || *(st+1) == '^' ) {
  1188.                             tw->telstate = ESCFOUND;
  1189.                         }
  1190.                         st++;            /* strip or accept ESC char */
  1191.                         break;
  1192.     
  1193.                     default:
  1194.                         if (*st++ > 127) {
  1195.                             if (st==mark)                            /*new addition */
  1196.                                 VSwrite(tw->vs,(char *) orig,1);    /* BYU LSC */
  1197.                              }
  1198.                         break;
  1199.                 }    // switch(*st)
  1200.             } // tw->telstate == STNORM
  1201.     } // while (st < mark)
  1202.     } // tw->termstate != DUMBTYPE
  1203. } /* parse */
  1204.  
  1205. void    SendNAWSinfo(WindRec *s, short horiz, short vert)
  1206. {
  1207.     char            blah[20];
  1208.     unsigned char    height, width;
  1209.  
  1210.     height = vert & 0xff;
  1211.     width = horiz & 0xff;
  1212.     
  1213.     /* 931112, ragge, NADA, KTH, ugly patch to not send IAC as window size  */
  1214.     if(height == 0xFF) height = 0xFE;
  1215.     if(width == 0xFF) width = 0xFE;
  1216.  
  1217.     netpush (s->port);
  1218.  
  1219. /* NCSA: syntax for command is:  IAC SB NAWS widthHI widthLO heightHI heightLO IAC SE */
  1220.  
  1221.     netwrite(s->port,"\377\372\037\000",4);
  1222.     sprintf(blah,"%c\000", width);
  1223.     netwrite(s->port,blah,2);
  1224.     sprintf(blah,"%c\377\360", height);
  1225.     netwrite(s->port,blah,3);
  1226.     opts_debug_print("SENT: IAC SB NAWS <data> IAC SE");        
  1227. }
  1228.  
  1229. /*
  1230.  * Implementation specific Kerberos routines
  1231.  */
  1232.  
  1233.  
  1234. /*
  1235.  * send_auth_opt
  1236.  */
  1237. void send_auth_opt (struct WindRec *tw)
  1238. {
  1239.     unsigned char *cp, buf[30];
  1240.     
  1241.     cp = buf;
  1242.     if (tw->authenticate) {
  1243.         sprintf((char *)cp, "%c%c%c", IAC, TEL_WILLTEL, OPT_AUTHENTICATION);    /* will authenticate */
  1244.         cp += 3;
  1245.         (tw->myopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1;
  1246.  
  1247.         if (tw->encrypt) {
  1248.             sprintf((char *)cp, "%c%c%c", IAC, TEL_WILLTEL, OPT_ENCRYPT);        /* will encrypt */
  1249.             cp += 3;
  1250.             (tw->myopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1;
  1251.         }
  1252.         netpush(tw->port);
  1253.         netwrite(tw->port, buf, cp - buf);
  1254.     }
  1255. }
  1256.  
  1257.  
  1258. #ifndef newauth
  1259. /*
  1260.  * net_write
  1261.  */
  1262. void net_write (struct WindRec *tw, char *buf, short length)
  1263. {
  1264.     netpush(tw->port);
  1265.     netwrite(tw->port, buf, length);
  1266. }
  1267.  
  1268.  
  1269. void tn_sendsub (struct WindRec *tw, short code, short request, char *cp, short length)
  1270. {
  1271.     long len;
  1272.     unsigned char *src, *lp, *limit;
  1273.     static char start[] = {IAC, TEL_SB, 0, 0};
  1274.     static char end[] = {IAC, TEL_SE};
  1275.  
  1276.     src = (unsigned char *)cp;
  1277.     limit = src + length;
  1278.     start[2] = code;
  1279.     start[3] = request;
  1280.     netpush(tw->port);
  1281.     netwrite(tw->port, start, 4);
  1282.  
  1283.     /*
  1284.      * Transmit the buffer. IACs must be doubled
  1285.      */
  1286.     if (*src == IAC) {                        /* check initial iac in buffer */
  1287.         netpush(tw->port);
  1288.         netwrite(tw->port, start, 1);        /* IAC */
  1289.     }
  1290.     while (src < limit) {
  1291.         lp = src+1;                            /* dont check first char */
  1292.         while (lp < limit) {                /* scan for IAC */
  1293.             if (*lp == IAC)
  1294.                 break;
  1295.             lp++;        
  1296.         }
  1297.         len = lp - src;
  1298.         if (lp < limit)                        /* if stopped on IAC */
  1299.             len++;                            /* include IAC in xmit */
  1300.  
  1301.         netpush(tw->port);
  1302.         netwrite(tw->port, src, len);
  1303.  
  1304.         src = lp;                            /* resume scanning */
  1305.     }
  1306.  
  1307.     netpush(tw->port);
  1308.     netwrite(tw->port, end, 2);
  1309. }
  1310. #endif
  1311.  
  1312.  
  1313. /*
  1314.  * getcname
  1315.  * Return a pointer to the cannonical host name
  1316.  */
  1317. char *getcname (WindRec *tw)
  1318. {
  1319.     char *cp;
  1320.     static char *b, buf[100];
  1321.  
  1322.     cp = 0;
  1323.     if (tw->cannon[0])
  1324.         cp = tw->cannon;
  1325.  
  1326. //    Doing the following is bad because we disposed of our init params!
  1327. //    else if ((*(*(ConnInitParams **)(tw->myInitParams))->session)->hostname)
  1328. //        cp = (char *)(*(*(ConnInitParams **)(tw->myInitParams))->session)->hostname;
  1329.  
  1330.     /* make a local copy to avoid locking handles */
  1331.     if (cp) {
  1332.         b = buf;        
  1333.         while (*cp)
  1334.             *b++ = *cp++;            
  1335.         *b++ = '\0';
  1336.         return buf;
  1337.     }
  1338.  
  1339.     return cp;
  1340. }
  1341.  
  1342.  
  1343. /*
  1344.  * encryptStatechange
  1345.  * Called when the encryption state changes
  1346.  */
  1347. #define kOurHit    32
  1348. void encryptStatechange (struct WindRec *tw)
  1349. {
  1350.     MyWDEFPatch(zoomDocProc , tw->wind, wDraw, kOurHit);
  1351. }
  1352.  
  1353. void DemangleLineMode(char *s, short mode)
  1354. {
  1355. #ifdef OPTS_DEBUG
  1356.     short     i;
  1357.     
  1358.     for (i=0; i<5; i++) {
  1359.         if (mode & (1 << i))
  1360.             strcat(s, LMmodes[i]);
  1361.     }
  1362. #endif
  1363. }
  1364.  
  1365. void DemangleLineModeShort(char *s, short mode)
  1366. {
  1367. #ifdef OPTS_DEBUG
  1368.     short     i;
  1369.     
  1370.     for (i=0; i<5; i++) {
  1371.         if (mode & (1 << i))
  1372.             strcat(s, LMmodeBits[i]);
  1373.         else
  1374.             strcat(s," ");
  1375.     }
  1376. #endif
  1377. }
  1378.  
  1379. #if 0    // Temp storage space - JMB 2.6b16.1
  1380.                                                 /* First check to see if we need to reply */
  1381.                                                 for (i=2;(tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3) {
  1382.                                                     if (!(tw->parsedat[i+1] & SLC_AWK)) break;
  1383.                                                     if ((unsigned char)(tw->parsedat[i+2])==IAC) i++;
  1384.                                                     }
  1385.  
  1386.                                                 /* if we do then send a reply */
  1387.                                                 if ((tw->parsedat[i]!=IAC) && (tw->parsedat[i]!='\0')) {
  1388.                                                 //    sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  1389.                                                 //    netwrite(tw->port,s,4);
  1390.                                                 //    opts_debug_print("SENT: IAC SB LINEMODE SLC");
  1391.     
  1392.  
  1393. #ifdef NEWSLC
  1394.                                                     for (i=2; (tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3)
  1395.                                                         {
  1396.                                                         if (!(tw->parsedat[i+1] & SLC_AWK))        /* no response of ACK set */
  1397.                                                             {
  1398.                                                             if (tw->parsedat[i+1] != SLC_NOSUPPORT)
  1399.                                                                 {
  1400.                                                                 sprintf(s,"%c%c%c",tw->parsedat[i],SLC_NOSUPPORT,0);
  1401. #ifdef OPTS_DEBUG
  1402.                                                                 sprintf(munger,"     %s NOSUPPORT 0",LMoptions[tw->parsedat[i]]);
  1403. #endif
  1404.                                                                 }
  1405.                                                             else        /* Acknowledge the No_Support case */
  1406.                                                                 {
  1407.                                                                 sprintf(s,"%c%c%c",tw->parsedat[i],SLC_AWK|SLC_NOSUPPORT,(char)0);
  1408. #ifdef OPTS_DEBUG
  1409.                                                                 sprintf(munger,"     %s NOSUPPORT|AWK 0",LMoptions[tw->parsedat[i]]);
  1410. #endif
  1411.                                                                 }                                                                
  1412. #ifdef OPTS_DEBUG
  1413.                                                             opts_debug_print(munger);
  1414. #endif
  1415.                                                             netwrite(tw->port,s,3);
  1416.                                                             }
  1417.                                                             if ((unsigned char)(tw->parsedat[i+2])==IAC) i++;
  1418.                                                         }
  1419.  
  1420. #else
  1421.                                                     for (i=2, lmslcflag=0; (tw->parsedat[i]!='\0') && (tw->parsedat[i]!=IAC); i+=3) {
  1422.                                                         // RFC 1184: If we get a response that is the same as the current setting, ignore it.  Technically, we
  1423.                                                         //    should check the value for a CANTCHANGE response to satisfy part 2 of Sec 5.5.  However, since we
  1424.                                                         //    advertised that key as CANTCHANGE in the first place, the server should not be changing it.  This
  1425.                                                         //    should be fixed later, however I don't see it causing big problems right now. - JMB 12/93
  1426.                                                         if (! ((((tw->parsedat[i+2] & SLC_LEVELBITS) == SLC_NOSUPPORT) && (tw->slc[tw->parsedat[i+1]] == -1))
  1427.                                                             || (((tw->parsedat[i+2] & SLC_LEVELBITS) == SLC_CANTCHANGE) && (tw->slc[tw->parsedat[i+1]] != -1)))) {
  1428.                                                             // If we get to this point, the value sent to us doesn't agree with what we want.
  1429.                                                             
  1430.                                                                 
  1431.                                                             if (!(tw->parsedat[i+1] & SLC_AWK)) {
  1432.                                                                 if (!lmslcflag) {
  1433.                                                                     lmslcflag = 1;        // Do this only once
  1434.                                                                     sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_SLC);
  1435.                                                                     netwrite(tw->port,s,4);
  1436.                                                                     opts_debug_print("SENT: IAC SB LINEMODE SLC");
  1437.                                                                     }
  1438.                                                             
  1439.                                                                 if (tw->slc[tw->parsedat[i]]==-1)
  1440.                                                                     {
  1441.                                                                     sprintf(s,"%c%c%c",tw->parsedat[i],SLC_NOSUPPORT,0);
  1442. #ifdef OPTS_DEBUG
  1443.                                                                     sprintf(munger,"     %s SLC_NOSUPPORT 0",LMoptions[tw->parsedat[i]]);
  1444. #endif
  1445.                                                                     }
  1446.                                                                 else
  1447.                                                                     {
  1448.                                                                     sprintf(s,"%c%c%c",tw->parsedat[i],SLC_CANTCHANGE,(char)tw->slc[tw->parsedat[i]]);
  1449. #ifdef OPTS_DEBUG
  1450.                                                                     sprintf(munger,"     %s SLC_CANTCHANGE %d",LMoptions[tw->parsedat[i]],
  1451.                                                                                                 (char)tw->slc[tw->parsedat[i]]);
  1452. #endif
  1453.                                                                     }                                                                
  1454. #ifdef OPTS_DEBUG
  1455.                                                                 opts_debug_print(munger);
  1456. #endif
  1457.                                                                 netwrite(tw->port,s,3);
  1458.                                                                 if (tw->parsedat[i+2]==IAC) i++;
  1459.                                                                 }
  1460.                                                             }
  1461.                                                         }
  1462.                                                         
  1463. #endif
  1464.                                                     if (lmslcflag) {
  1465.                                                         sprintf(s,"%c%c",IAC,TEL_SE);
  1466.                                                         netwrite(tw->port,s,2);
  1467.                                                         }
  1468.                                                     }
  1469.  
  1470.                                                     /* otherwise just exit */
  1471.                                                     }
  1472.                                                     break;
  1473. #endif
  1474.